﻿using System;
using System.ComponentModel;
using System.Reflection;
using System.Threading;
using System.Windows;
using System.Windows.Input;
using Plugins.UserControls;
using StockModel;
using Utils;
using Utils.Wpf;

namespace PluginSample2.Historical
{
	internal class ControlPanelVM : ViewModelBase
	{
		#region Attributes

		private readonly EngineSettings _settings;
		private readonly Engine _engine;
		
		#endregion

		#region Properties

		public ICommand RunStrategyCommand { get; private set; }

		public PresetSelectorVM<Historical.EngineSettings> PresetSelectorVM { get; private set; }
        public StockSelectorVM StockSelectorVM { get; private set; }
        public DateSelectorVM DateSelectorVM { get; private set; }
        public HourSelectorVM HourSelectorVM { get; private set; }
		public StockParametersSelectorVM StockParametersSelectorVM { get; private set; }
		public StrategyControlVM StrategyControlVM { get; private set; }
		public CustomDataParametersVM CustomDataParametersVM { get; private set; }

		#endregion

		#region Public Methods

		public ControlPanelVM(RawStockDataSource rawStockDataSource, Engine engine, QuotationDataSource quotationDataSource)
		{
			_engine = engine;

			this.RunStrategyCommand = new DelegateCommand(ExecuteRunStrategy, CanRunStrategy);

            this.StockSelectorVM = new StockSelectorVM(rawStockDataSource);
            this.DateSelectorVM = new DateSelectorVM(rawStockDataSource, quotationDataSource);
            this.HourSelectorVM = new HourSelectorVM();
			this.StockParametersSelectorVM = new StockParametersSelectorVM();
			this.StrategyControlVM = new StrategyControlVM();
			this.CustomDataParametersVM = new CustomDataParametersVM();

			// Create settings
			_settings = new EngineSettings(this.StrategyControlVM.Data, this.DateSelectorVM.Data, this.HourSelectorVM.Data, this.StockParametersSelectorVM.Data, this.StockSelectorVM.Data, this.CustomDataParametersVM.Data);
			_engine.Settings = _settings;
			
			this.SetDefaultValues();
			this.PresetSelectorVM = new PresetSelectorVM<Historical.EngineSettings>(Assembly.GetExecutingAssembly().GetName().Name + Properties.Settings.Default.HistoricalPresetsFilename, _settings);

            this.StockSelectorVM.PropertyChanged += StockSelectorVM_PropertyChanged; // Local object
		}

		#endregion

		#region Event Handlers

		private void StockSelectorVM_PropertyChanged(object sender, PropertyChangedEventArgs e)
		{
			if (e.PropertyName == "IsStockSelected" && this.StockSelectorVM.IsStockSelected)
			{
				this.DateSelectorVM.LoadAvailableDays(this.StockSelectorVM.SelectedStockName);
			}
		}

		#endregion

		#region Private Methods

		private void MainExecutionThread()
		{
			try
			{
				_engine.Execute();
			}
			catch (Exception ex)
			{
				ExceptionLogger.LogException("Unexpected error executing a historical strategy", ex, false);
				MessageBox.Show("Unexpected error executing the strategy.\nError message: " + ex.Message, "Unexpected error", MessageBoxButton.OK, MessageBoxImage.Error);
			}
			finally
			{
				base.IsBusy = false;				
			}
		}

		private void ExecuteRunStrategy()
		{
			base.IsBusy = true;

			Thread backgroundExecutor = new Thread(this.MainExecutionThread);
			backgroundExecutor.Name = "Plugin Sample 2 Historical Execution Thread";
			backgroundExecutor.Start();
		}

		private bool CanRunStrategy()
		{
			return !this.StrategyControlVM.HasValidationErrors && !this.DateSelectorVM.HasValidationErrors && !this.HourSelectorVM.HasValidationErrors && this.StockSelectorVM.IsStockSelected;
		}

		private void SetDefaultValues()
		{
			_settings.QuantityToBuy = 1;
			_settings.PercentageFee = 0m;
			_settings.FixedFeePerItem = 0.9m;
			_settings.FixedReserve = 320;
			_settings.UseAllDays = true;
			_settings.StartWithOpening = true;
			_settings.LastOperationStart = new TimeSpan(17,0,0);
			_settings.ForcedCloseTime = new TimeSpan(17,29,0);
			_settings.ValueMultiplier = 1;
		}

		#endregion

	}
}
